package cn.edu.wzu.openlearning.controller;


import cn.edu.wzu.openlearning.pojo.*;
import cn.edu.wzu.openlearning.service.WordService;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpSession;
import java.util.*;
import java.io.IOException;

@RequestMapping(value = "word")
@Controller
public class WordController {
    @Autowired
    private WordService wordService;

    /**
     * 首页的页面访问，只设置单纯的跳转
     *
     * @param needPage
     * @return 页面访问
     */
    @RequestMapping(value = {"{needPage}"})
    public String pageViewer(@PathVariable String needPage) {
        return needPage;
    }

    /**
     * 查词典
     *
     * @param start
     * @param sizeByOnePage
     * @param model
     * @return
     */
    @RequestMapping({"wordDict", "/"})
    public String selectWordDict(
            @RequestParam(value = "start", defaultValue = "1") int start,
            @RequestParam(value = "sizeByOnePage", defaultValue = "50") int sizeByOnePage,
            Model model
    ) {

        PageInfo<Word> wordPageInfo = wordService.listWordDict(start, sizeByOnePage);
        model.addAttribute("pageWordDict", wordPageInfo);
        return "wordDict";
    }

    /**
     * 搜索单词
     *
     * @param model
     * @param word
     * @return
     */
    @RequestMapping({"searchWord"})
    public String searchWordDict(Model model,
                                 @RequestParam("word") String word) {
        Word wordInfo = wordService.selectWord(word);
        model.addAttribute("wordInfo", wordInfo);
        return "wordSearch";
    }

    /**
     * 用户单词书上传
     *
     * @param file
     * @param bookNickname
     * @param session
     * @return
     * @throws IOException
     */
    @RequestMapping(value = {"receiveCSVWordDict.do"}, method = {RequestMethod.POST})
    public String receiveCSVWordDict(@RequestParam("file") MultipartFile file,
                                     String bookNickname,
                                     HttpSession session
    ) throws IOException {
        List<Map<String, String>> names = (List<Map<String, String>>) session.getAttribute("names");
        if (names == null) {
            names = new ArrayList<>();
            HashMap<String, String> map = new HashMap<>();
            map.put("nickname", bookNickname);
            map.put("value", "false");
            names.add(map);

        } else {
            HashMap<String, String> map = new HashMap<>();
            map.put("nickname", bookNickname);
            map.put("value", "false");
            names.add(map);

        }
        session.setAttribute("names", names);
        wordService.handleFileChangeUserWordBook(file.getInputStream(), bookNickname, session);
        return "redirect:WorkBookUpdate";
    }

    /**
     * 用户设置单词的环境
     *
     * @return
     */
    @RequestMapping(value = {"setting"})
    public String userWordSetting(HttpSession session) {
        User user = (User) session.getAttribute("user");
        // 获取用户的设置环境，如果没有则创建
        WordReciteSetting setting = wordService.getWordSettingByUser(user);
        session.setAttribute("setting", setting);
        //  这里要写一个包装类，获得到 真实的单词书id 和包装的POJO UserWordBook 包括单词的数量， 以及已经背诵的数量（后续补充）
        // 查询所有的单词书
        List<QueryWordBooks> wordBooks = wordService.listWordBooks(session);
        session.setAttribute("wordbooks", wordBooks);
        return "WordSetting";
    }

    /**
     * 修改用户的环境
     *
     * @param session
     * @return
     */
    @RequestMapping(value = {"setting.do"}, method = {RequestMethod.POST,})
    public String alterUserWordSetting(String seed, Integer reciteNum, String selectedBookUuid, HttpSession session, Model model) {
        User user = (User) session.getAttribute("user");
        wordService.alterWordReciteSettingByUserId(seed, reciteNum, selectedBookUuid, user.getUserId());
        // 更新显示 用户的设置环境
        WordReciteSetting setting = wordService.getWordSettingByUser(user);
        session.setAttribute("setting", setting);
        model.addAttribute("info", "设置成功");
        return "WordSetting";
    }


    /**
     * 背单词 核心算法
     * Step1：背诵生单词 20
     * Step2：复习生单词 40
     * Step3：复习熟单词 60
     * Step4：对不熟的单词进行最后一次复习。直到复习结束 80
     * Step5：提交更新需要降低和提高熟悉度的单词，进行打卡 (但是不显示) 100
     * Step6：删除Step，显示打卡（实际上早就打了）
     *
     * @param session
     * @return
     */
    @RequestMapping(value = "reciteWord")
    public String reciteWord(HttpSession session, Model model) {
        session.setMaxInactiveInterval(60 * 60 * 12);
        // Step1
        User user = (User) session.getAttribute("user");
        // 判断用户是否有选择单词书，没有直接打回去
        WordReciteSetting setting = wordService.getWordSettingByUser(user);
        if (setting.getUseWordBookUuid() == null) {
            model.addAttribute("error", "请选择单词书");
            return "forward:/word/setting";
        }
        Integer step = (Integer) session.getAttribute("step");
        // 上述部分测试成功
        if (step == null || step == 1) {
            session.setAttribute("step", 1);
            return "forward:/word/reciteWordStep1.do";
        } else if (step == 2) {
            session.setAttribute("step", 2);
            return "forward:/word/reciteWordStep2.do";
        } else if (step == 3) {
            session.setAttribute("step", 3);
            return "forward:/word/reciteWordStep3.do";
        } else if (step == 4) {
            session.setAttribute("step", 4);
            return "forward:/word/reciteWordStep4.do";
        }
        return "WordRecite";
    }

    @RequestMapping(value = "reciteWordStep1.do")
    public String reciteWordStep1(HttpSession session) {
        // Step1
        User user = (User) session.getAttribute("user");
        Integer step = (Integer) session.getAttribute("step");
        if (step != null && step == 1) {
            // 继续
            List<Word> wordList = wordService.selectRawWords(user);
            session.setAttribute("step1RawWordList", wordList);
            return "WordReciteStep1";
        }
        return "WordRecite";
    }

    @RequestMapping(value = "reciteWordStep2.do")
    public String reciteWordStep2(HttpSession session) {
        User user = (User) session.getAttribute("user");
        Integer step = (Integer) session.getAttribute("step");
        if (step != null && (step == 1 || step == 2)) {
            // 更新session 的 Step
            session.setAttribute("step", 2);
            // 记录完毕后进入下一阶段，复习生单词，还是一个页面，但是这次是找错，并且不显示单词翻译
            return "WordReciteStep2";
        }
        return "WordRecite";
    }

    @RequestMapping(value = "reciteWordStep3.do")
    public String reciteWordStep3(HttpSession session) {
        User user = (User) session.getAttribute("user");
        Integer step = (Integer) session.getAttribute("step");
        if (step != null && (step == 2 || step == 3)) {
            session.setAttribute("step", 3);
            // 查询熟单词
            List<Word> familiarWords = wordService.selectFamiliarWords(user);
            session.setAttribute("step3familiarWords", familiarWords);
            return "WordReciteStep3";
        } else if( step == null || step == 3) {
            session.setAttribute("step", 3);
            // 查询熟单词
            List<Word> familiarWords = wordService.selectFamiliarWords(user);
            session.setAttribute("step3familiarWords", familiarWords);
            return "WordReciteStep3";
        } else if (step == 4){
            return "redirect:reciteWord";
        }

        return "WordRecite";
    }

    @RequestMapping(value = "reciteWordStep4.do")
    public String reciteWordStep4(HttpSession session) {
        User user = (User) session.getAttribute("user");
        Integer step = (Integer) session.getAttribute("step");
        if (step != null && (step == 3 || step == 4)) {
            session.setAttribute("step", 4);
            Set<Word> finalWordReview = new HashSet<>();
            Set<Word> wordEasyList = (Set<Word>) session.getAttribute("wordEasyList");
            Set<Word> wordNoSure = (Set<Word>) session.getAttribute("wordNoSure");
            Set<Word> wordForget = (Set<Word>) session.getAttribute("wordForget");
            if (wordEasyList == null) {
                wordEasyList = new HashSet<>();
                session.setAttribute("wordEasyList",wordEasyList);
            }
            if (wordNoSure != null) {
                finalWordReview.addAll(wordNoSure);
            } else {
                wordNoSure = new HashSet<>();
                session.setAttribute("wordNoSure",wordNoSure);
            }
            if (wordForget != null) {
                finalWordReview.addAll(wordForget);
            } else {
                wordForget = new HashSet<>();
                session.setAttribute("wordForget",wordForget);
            }
            if(finalWordReview.isEmpty()){
                session.removeAttribute("step");
                // 清空 step，设置 session 打卡成功
                session.setAttribute("clockIn","今日成功打卡！");
                // 完全熟悉的单词设置为 7
                // 生单词和 忘记的熟单词 设置为1
                // 其他的单词都是自增 +1
                wordService.wordReciteClockIn(session);

                return "WordRecite";

            } else {
                if (session.getAttribute("step4WordNoSure") == null){
                    Set<Word> step4WordNoSure = new HashSet<>();
                    for(Word word :wordNoSure){
                        step4WordNoSure.add(
                                new Word(word.getWordId(),
                                        word.getWord(),
                                        word.getEnglishPronunciation(),
                                        word.getAmericaPronunciation(),
                                        word.getMeaning()
                                )
                        );
                    }
                    session.setAttribute("step4WordNoSure", step4WordNoSure);
                }

                if (session.getAttribute("step4WordForget") == null){
                    Set<Word> step4WordForget = new HashSet<>();
                    for(Word word : wordForget){
                        step4WordForget.add(
                                new Word(word.getWordId(),
                                        word.getWord(),
                                        word.getEnglishPronunciation(),
                                        word.getAmericaPronunciation(),
                                        word.getMeaning()
                                )
                        );
                    }
                    session.setAttribute("step4WordForget", step4WordForget);
                }
                Set<Word> step4WordNoSure = (Set<Word>) session.getAttribute("step4WordNoSure");
                Set<Word> step4WordForget = (Set<Word>) session.getAttribute("step4WordForget");
                Set<Word> step4FinalWordReview = new HashSet<>();
                step4FinalWordReview.addAll(step4WordNoSure);
                step4FinalWordReview.addAll(step4WordForget);
                if (step4FinalWordReview.isEmpty()){
                    session.removeAttribute("step");
                    // 清空 step，设置 session 打卡成功
                    session.setAttribute("clockIn","今日成功打卡！");
                    wordService.wordReciteClockIn(session);
                    return "WordRecite";

                } else {

                    Set<Word> step4FinalWordRealReview = new HashSet<>();
                    List<Word> step1RawWordList = (List<Word>) session.getAttribute("step1RawWordList");
                    if (step1RawWordList == null)
                        step1RawWordList = new ArrayList<>();
                    for (Word word1 : step1RawWordList){
                        for (Word word2 : step4FinalWordReview){
                            if (word1.equals(word2)){
                                step4FinalWordRealReview.add(word1);
                            }
                        }
                    }
                    List<Word> step3familiarWords = (List<Word>) session.getAttribute("step3familiarWords");
                    if (step3familiarWords == null)
                        step3familiarWords = new ArrayList<>();
                    for (Word word1 : step3familiarWords){
                        for (Word word2 : step4FinalWordReview){
                            if (word1.equals(word2)){
                                step4FinalWordRealReview.add(word1);
                            }
                        }
                    }
                    session.setAttribute("step4FinalWordReview", step4FinalWordRealReview);
                    return "WordReciteStep4";
                }
            }

        }
        return "WordRecite";
    }

    @RequestMapping(value = "clearUserRecitedWord.do", method = RequestMethod.POST)
    public String clearUserRecitedWord(Boolean allClear,HttpSession session, Model model){
        User user = (User) session.getAttribute("user");
        wordService.clearUserRecitedWord(allClear,user);
        model.addAttribute("info", "已经成功清空单词");
        return "forward:/word/setting";
    }

    @ResponseBody
    @RequestMapping(value = "wordEasy.do", method = RequestMethod.POST)
    public String wordEasy(@RequestBody Word word, HttpSession session) {
        User user = (User) session.getAttribute("user");
        Set<Word> wordEasyList = (Set<Word>) session.getAttribute("wordEasyList");

        if (wordEasyList == null) {
            // 如果单词列表很简单，那么就显示为
            wordEasyList = new HashSet<>();
            session.setAttribute("wordEasyList", wordEasyList);
        }
        if (word.getWordId() != null && word.getWord() != null) {
            wordEasyList.add(word);

            return "{'info':'success'}";
        } else {
            return "{'info':'error'}";
        }
    }

    @ResponseBody
    @RequestMapping(value = "wordNoSure.do", method = RequestMethod.POST)
    public String wordNoSure(@RequestBody Word word, HttpSession session) {
        User user = (User) session.getAttribute("user");
        Set<Word> wordNoSure = (Set<Word>) session.getAttribute("wordNoSure");

        if (wordNoSure == null) {
            // 如果单词列表很简单，那么就显示为
            wordNoSure = new HashSet<>();
            session.setAttribute("wordNoSure", wordNoSure);
        }
        if (word.getWordId() != null && word.getWord() != null) {
            wordNoSure.add(word);

            return "{'info':'success'}";
        } else {
            return "{'info':'error'}";
        }
    }

    @ResponseBody
    @RequestMapping(value = "wordForget.do", method = RequestMethod.POST)
    public String wordForget(@RequestBody Word word, HttpSession session) {
        User user = (User) session.getAttribute("user");
        Set<Word> wordForget = (Set<Word>) session.getAttribute("wordForget");

        if (wordForget == null) {
            // 如果单词列表很简单，那么就显示为
            wordForget = new HashSet<>();
            session.setAttribute("wordForget", wordForget);
        }
        if (word.getWordId() != null && word.getWord() != null) {
            wordForget.add(word);

            return "{'info':'success'}";
        } else {
            return "{'info':'error'}";
        }
    }

    @ResponseBody
    @RequestMapping(value = "wordRemember.do", method = RequestMethod.POST)
    public String wordRemember(@RequestBody Word word, HttpSession session) {
        User user = (User) session.getAttribute("user");
        Set<Word> step4WordNoSure = (Set<Word>) session.getAttribute("step4WordNoSure");
        Set<Word> step4WordForget = (Set<Word>) session.getAttribute("step4WordForget");

        if (word.getWordId() != null && word.getWord() != null) {

            for (Word word1: step4WordNoSure) {
                if (word1.equals(word)){
                    step4WordNoSure.remove(word1);
                }
            }

            for (Word word2: step4WordForget) {
                if (word2.equals(word)){
                    step4WordForget.remove(word2);
                }
            }

            return "{'info':'success'}";
        } else {
            return "{'info':'error'}";
        }
    }




    @RequestMapping(value = "clearSession.do", method = RequestMethod.GET)
    public String clearSession(HttpSession session) {

        Enumeration em = session.getAttributeNames();
        while(em.hasMoreElements()){
            String obj = (String) em.nextElement();
            if(!obj.equals("user"))
                session.removeAttribute(obj);
        }
        return "redirect:WordRecite";
    }


}
